home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / scsiDiskBoot / sun3.md / devSCSI0.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-19  |  28.2 KB  |  922 lines

  1. /* 
  2.  * devSCSI0.c --
  3.  *
  4.  *    Driver routines specific to the original Sun Host Adaptor.
  5.  *    This lives either on the Multibus or the VME.  It does
  6.  *    not support dis-connect/connect.
  7.  *     This information is derived from Sun's "Manual for Sun SCSI
  8.  *    Programmers", which details the layout of the this implementation
  9.  *    of the Host Adaptor, the device that interfaces to the SCSI Bus.
  10.  *
  11.  * Copyright 1986 Regents of the University of California
  12.  * Permission to use, copy, modify, and distribute this
  13.  * software and its documentation for any purpose and without
  14.  * fee is hereby granted, provided that the above copyright
  15.  * notice appear in all copies.  The University of California
  16.  * makes no representations about the suitability of this
  17.  * software for any purpose.  It is provided "as is" without
  18.  * express or implied warranty.
  19.  */
  20.  
  21. #ifdef notdef
  22. static char rcsid[] = "$Header: /sprite/src/kernel/dev/sun3.md/RCS/devSCSI0.c,v 8.3 89/05/24 07:51:26 rab Exp $ SPRITE (Berkeley)";
  23. #endif not lint
  24.  
  25.  
  26. #include "sprite.h"
  27. #include "mach.h"
  28. #include "../sync.h"
  29. #include "scsi0.h"
  30. #include "dev.h"
  31. #include "devInt.h"
  32. #include "scsi.h"
  33. #include "scsiHBA.h"
  34. #include "scsiDevice.h"
  35. #include "devMultibus.h"
  36. #include "stdlib.h"
  37. #include "boot.h"
  38. #include "machMon.h"
  39.  
  40. #ifdef SCSI0_BOOT
  41. /*
  42.  * The device registers for the original Sun SCSI Host Adaptor.
  43.  * Through these registers the SCSI bus is controlled.  There are the
  44.  * usual status and control bits, and there are also registers through
  45.  * which command blocks and status blocks are transmitted.  This format
  46.  * is defined on Page 10. of Sun's SCSI Programmers' Manual.
  47.  */
  48. typedef struct CtrlRegs {
  49.     unsigned char data;        /* Data register.  Contains the ID of the
  50.                  * SCSI "target", or controller, for the 
  51.                  * SELECT phase. Also, leftover odd bytes
  52.                  * are left here after a read. */
  53.     unsigned char pad1;        /* The other half of the data register which
  54.                  * is never used by us */
  55.     unsigned char commandStatus;/* Command and status blocks are passed
  56.                  * in and out through this */
  57.     unsigned char pad2;        /* The other half of the commandStatus register
  58.                  * which never contains useful information */
  59.     unsigned short control;    /* The SCSI interface control register.
  60.                  * Bits are defined below */
  61.     unsigned short pad3;
  62.     unsigned int dmaAddress;    /* Target address for DMA */
  63.     short     dmaCount;    /* Number of bytes for DMA.  Initialize this
  64.                  * this to minus the byte count minus 1 more,
  65.                  * and the device increments to -1. If this
  66.                  * is 0 or 1 after a transfer then there was
  67.                  * a DMA overrun. */
  68.     unsigned char pad4;
  69.     unsigned char intrVector;    /* For VME, Index into autovector */
  70. } CtrlRegs;
  71.  
  72. /*
  73.  * Control bits in the SCSI Host Interface control register.
  74.  *
  75.  *    SCSI_PARITY_ERROR There was a parity error on the SCSI bus.
  76.  *    SCSI_BUS_ERROR    There was a bus error on the SCSI bus.
  77.  *    SCSI_ODD_LENGTH An odd byte is left over in the data register after
  78.  *            a read or write.
  79.  *    SCSI_INTERRUPT_REQUEST bit checked by polling routine.  If a command
  80.  *            block is sent and the SCSI_INTERRUPT_ENABLE bit is
  81.  *            NOT set, then the appropriate thing to do is to
  82.  *            wait around (poll) until this bit is set.
  83.  *    SCSI_REQUEST    Set by controller to start byte passing handshake.
  84.  *    SCSI_MESSAGE    Set by a controller during message phase.
  85.  *    SCSI_COMMAND    Set during the command, status, and messages phase.
  86.  *    SCSI_INPUT    If set means data (or commandStatus) set by device.
  87.  *    SCSI_PARITY    Used to test the parity checking hardware.
  88.  *    SCSI_BUSY    Set by controller after it has been selected.
  89.  *  The following bits can be set by the CPU.
  90.  *    SCSI_SELECT    Set by the host when it want to select a controller.
  91.  *    SCSI_RESET    Set by the host when it want to reset the SCSI bus.
  92.  *    SCSI_PARITY_ENABLE    Enable parity checking on transfer
  93.  *    SCSI_WORD_MODE        Send 2 bytes at a time
  94.  *    SCSI_DMA_ENABLE        Do DMA, always used.
  95.  *    SCSI_INTERRUPT_ENABLE    Interrupt upon completion.
  96.  */
  97. #define SCSI_PARITY_ERROR        0x8000
  98. #define SCSI_BUS_ERROR            0x4000
  99. #define SCSI_ODD_LENGTH            0x2000
  100. #define SCSI_INTERRUPT_REQUEST        0x1000
  101. #define SCSI_REQUEST            0x0800
  102. #define SCSI_MESSAGE            0x0400
  103. #define SCSI_COMMAND            0x0200
  104. #define SCSI_INPUT            0x0100
  105. #define SCSI_PARITY            0x0080
  106. #define SCSI_BUSY            0x0040
  107. #define SCSI_SELECT            0x0020
  108. #define SCSI_RESET            0x0010
  109. #define SCSI_PARITY_ENABLE        0x0008
  110. #define SCSI_WORD_MODE            0x0004
  111. #define SCSI_DMA_ENABLE            0x0002
  112. #define SCSI_INTERRUPT_ENABLE        0x0001
  113.  
  114. /* Forward declaration. */
  115. typedef struct Controller Controller;
  116.  
  117. /*
  118.  * Device - The data structure containing information about a device. One of
  119.  * these structure is kept for each attached device. Note that is structure
  120.  * is casted into a ScsiDevice and returned to higher level software.
  121.  * This implies that the ScsiDevice must be the first field in this
  122.  * structure.
  123.  */
  124.  
  125. typedef struct Device {
  126.     ScsiDevice handle;    /* Scsi Device handle. This is the only part
  127.              * of this structure visible to higher 
  128.              * level software. MUST BE FIRST FIELD IN STRUCTURE.
  129.              */
  130.     int    targetID;    /* SCSI Target ID of this device. Note that
  131.              * the LUN is store in the device handle.
  132.              */
  133.     Controller *ctrlPtr;    /* Controller to which device is attached. */
  134.            /*
  135.             * The following part of this structure is 
  136.             * used to handle SCSI commands that return 
  137.             * CHECK status. To handle the REQUEST SENSE
  138.             * command we must: 1) Save the state of the current
  139.             * command into the "struct FrozenCommand". 2) Submit
  140.             * a request sense command formatted in SenseCmd
  141.             * to the device.
  142.             */
  143.     struct FrozenCommand {               
  144.     ScsiCmd    *scsiCmdPtr;      /* The frozen command. */
  145.     unsigned char statusByte; /* It's SCSI status byte, Will always have
  146.                    * the check bit set.  */
  147.     int amountTransferred;    /* Number of bytes transferred by this 
  148.                    * command.  */
  149.     } frozen;    
  150.     char senseBuffer[DEV_MAX_SENSE_BYTES]; /* Data buffer for request sense */
  151.     ScsiCmd        SenseCmd;         /* Request sense command buffer. */
  152. } Device;
  153.  
  154. /*
  155.  * Controller - The Data structure describing a sun SCSI0 controller. One
  156.  * of these structures exists for each active SCSI0 HBA on the system. Each
  157.  * controller may have from zero to 56 (7 targets each with 8 logical units)
  158.  * devices attached to it. 
  159.  */
  160. struct Controller {
  161.     volatile CtrlRegs *regsPtr;    /* Pointer to the registers
  162.                                     of this controller. */
  163.     int        dmaState;    /* DMA state for this controller, defined below. */
  164.     char    *name;    /* String for error message for this controller.  */
  165.     DevCtrlQueues devQueues;    /* Device queues for devices attached to this
  166.                  * controller.     */
  167.     Sync_Semaphore mutex; /* Lock protecting controller's data structures. */
  168.     Device     *devPtr;       /* Current active command. */
  169.     ScsiCmd   *scsiCmdPtr; /* Current active command. */
  170.     Address   dmaBuffer;  /* dma buffer allocated for request. */
  171.     Device  *devicePtr; /* Pointers to the device
  172.                                * attached to the
  173.                    * controller index by. */
  174.  
  175. };
  176.  
  177. /* 
  178.  * SCSI_WAIT_LENGTH - the number of microseconds that the host waits for
  179.  *    various control lines to be set on the SCSI bus.  The largest wait
  180.  *    time is when a controller is being selected.  This delay is
  181.  *    called the Bus Abort delay and is about 250 milliseconds.
  182.  */
  183. #define SCSI_WAIT_LENGTH        250000
  184.  
  185. /*
  186.  * Possible values for the dmaState state field of a controller.
  187.  *
  188.  * DMA_RECEIVE  - data is being received from the device, such as on
  189.  *    a read, inquiry, or request sense.
  190.  * DMA_SEND     - data is being send to the device, such as on a write.
  191.  * DMA_INACTIVE - no data needs to be transferred.
  192.  */
  193.  
  194. #define DMA_RECEIVE 0
  195. #define    DMA_SEND 1
  196. #define    DMA_INACTIVE 2
  197. /*
  198.  * Test, mark, and unmark the controller as busy.
  199.  */
  200. #define    IS_CTRL_BUSY(ctrlPtr)    ((ctrlPtr)->scsiCmdPtr != (ScsiCmd *) NIL)
  201. #define    SET_CTRL_BUSY(ctrlPtr,scsiCmdPtr) \
  202.         ((ctrlPtr)->scsiCmdPtr = (scsiCmdPtr))
  203. #define    SET_CTRL_FREE(ctrlPtr)    ((ctrlPtr)->scsiCmdPtr = (ScsiCmd *) NIL)
  204.  
  205. /*
  206.  * MAX_SCSI0_CTRLS - Maximum number of SCSI0 controllers attached to the
  207.  *             system. We set this to the maximum number of VME slots
  208.  *             in any Sun2 system currently available.
  209.  */
  210. #define    MAX_SCSI0_CTRLS    1
  211. static Controller *Controllers[MAX_SCSI0_CTRLS];
  212. /*
  213.  * Highest number controller we have probed for.
  214.  */
  215. static int numSCSI0Controllers = 0;
  216. static int doneC;
  217. static void RequestDone();
  218. static ReturnStatus Wait();
  219.  
  220.  
  221. /*
  222.  *----------------------------------------------------------------------
  223.  *
  224.  * Reset --
  225.  *
  226.  *    Reset a SCSI bus controlled by the orignial Sun Host Adaptor.
  227.  *
  228.  * Results:
  229.  *    None.
  230.  *
  231.  * Side effects:
  232.  *    Reset the controller.
  233.  *
  234.  *----------------------------------------------------------------------
  235.  */
  236. static void
  237. Reset(ctrlPtr)
  238.     Controller *ctrlPtr;
  239. {
  240.     volatile CtrlRegs *regsPtr = (volatile CtrlRegs *)ctrlPtr->regsPtr;
  241.  
  242.     regsPtr->control = SCSI_RESET;
  243.     MACH_DELAY(100);
  244.     regsPtr->control = 0;
  245. }
  246.  
  247. /*
  248.  *----------------------------------------------------------------------
  249.  *
  250.  * SendCommand --
  251.  *
  252.  *      Send a command to a controller on the old-style SCSI Host Adaptor
  253.  *      indicated by devPtr.  
  254.  *
  255.  *    Note: the ID of the controller is never placed on the bus
  256.  *    (contrary to standard protocol, but necessary for the early Sun
  257.  *    SCSI interface).
  258.  *
  259.  * Results:
  260.  *    An error code.
  261.  *
  262.  * Side effects:
  263.  *    Those of the command (Read, write etc.)
  264.  *
  265.  *----------------------------------------------------------------------
  266.  */
  267. static ReturnStatus
  268. SendCommand(devPtr, scsiCmdPtr)
  269.     Device    *devPtr;        /* Device to sent to. */
  270.     ScsiCmd    *scsiCmdPtr;        /* Command to send. */
  271. {
  272.     register ReturnStatus status;
  273.     register volatile CtrlRegs *regsPtr;/* Host Adaptor registers */
  274.     char *charPtr;            /* Used to put the control block
  275.                      * into the commandStatus register */
  276.     int bits = 0;            /* variable bits to OR into control */
  277.     int targetID;            /* Id of the SCSI device to select */
  278.     int size;                /* Number of bytes to transfer */
  279.     Address addr;            /* Kernel address of transfer */
  280.     Controller    *ctrlPtr;        /* HBA of device. */
  281.     int    i;
  282.  
  283.     /*
  284.      * Set current active device and command for this controller.
  285.      */
  286.     ctrlPtr = devPtr->ctrlPtr;
  287.     SET_CTRL_BUSY(ctrlPtr,scsiCmdPtr);
  288.     ctrlPtr->dmaBuffer = (Address) NIL;
  289.     ctrlPtr->devPtr = devPtr;
  290.     size = scsiCmdPtr->bufferLen;
  291.     addr = scsiCmdPtr->buffer;
  292.     targetID = devPtr->targetID;
  293.     regsPtr = (volatile CtrlRegs *)ctrlPtr->regsPtr;
  294.     if (size == 0) {
  295.     ctrlPtr->dmaState = DMA_INACTIVE;
  296.     } else {
  297.     ctrlPtr->dmaState = (scsiCmdPtr->dataToDevice) ? DMA_SEND :
  298.                              DMA_RECEIVE;
  299.     }
  300.     if (ctrlPtr->dmaState != DMA_INACTIVE) {
  301.     ctrlPtr->dmaBuffer = addr = VmMach_DMAAlloc(size,scsiCmdPtr->buffer);
  302.     }
  303.     Mach_MonPrintf("scsi cmd %d/%d size %d addr 0x%x dma addr 0x%x\n",
  304.         scsiCmdPtr->commandBlock[0],
  305.         scsiCmdPtr->commandBlockLen,size, scsiCmdPtr->buffer, addr);
  306.    /*
  307.      * Check against a continuously busy bus.  This stupid condition would
  308.      * fool the code below that tries to select a device.
  309.      */
  310.     for (i=0 ; i < SCSI_WAIT_LENGTH ; i++) {
  311.     if ((regsPtr->control & SCSI_BUSY) == 0) {
  312.         break;
  313.     } else {
  314.         MACH_DELAY(10);
  315.     }
  316.     }
  317.     if (i == SCSI_WAIT_LENGTH) {
  318.     Reset(ctrlPtr);
  319.     return(FAILURE);
  320.     }
  321.     /*
  322.      * Select the device.  Sun's SCSI Programmer's Manual recommends
  323.      * resetting the SCSI_WORD_MODE bit so that the byte packing hardware
  324.      * is reset and the data byte that has the target ID gets transfered
  325.      * correctly.  After this, the target's ID is put in the data register,
  326.      * the SELECT bit is set, and we wait until the device responds
  327.      * by setting the BUSY bit.  The ID bit of the host adaptor is not
  328.      * put in the data word because of problems with Sun's Host Adaptor.
  329.      */
  330.     regsPtr->control = 0;
  331.     regsPtr->data = (1 << targetID);
  332.     regsPtr->control = SCSI_SELECT;
  333.     status = Wait(ctrlPtr, SCSI_BUSY, FALSE);
  334.     if (status != SUCCESS) {
  335.     regsPtr->data = 0;
  336.     regsPtr->control = 0;
  337.     return(status);
  338.     }
  339.     /*
  340.      * Set up the interface's registers for the transfer.  The DMA address
  341.      * is relative to the multibus memory so the kernel's base address
  342.      * for multibus memory is subtracted from 'addr'. The host adaptor
  343.      * increments the dmaCount register until it reaches -1, hence the
  344.      * funny initialization. See page 4 of Sun's SCSI Prog. Manual.
  345.      */
  346.     regsPtr->dmaAddress = (int)(addr - VMMACH_DMA_START_ADDR);
  347.     regsPtr->dmaCount = -size - 1;
  348.     bits = SCSI_WORD_MODE | SCSI_DMA_ENABLE;
  349.     regsPtr->control = bits;
  350.  
  351.     /*
  352.      * Stuff the control block through the commandStatus register.
  353.      * The handshake on the SCSI bus is visible here:  we have to
  354.      * wait for the Request line on the SCSI bus to be raised before
  355.      * we can send the next command byte to the controller.  All commands
  356.      * are of "group 0" which means they are 6 bytes long.
  357.      */
  358.     charPtr = scsiCmdPtr->commandBlock;
  359.     for (i=0 ; i < scsiCmdPtr->commandBlockLen ; i++) {
  360.     status = Wait(ctrlPtr, SCSI_REQUEST, TRUE);
  361.     if (status != SUCCESS) {
  362.         return(status);
  363.     }
  364.     /*
  365.      * The device keeps the Control/Data line set while it
  366.      * is accepting control block bytes.
  367.      */
  368.     if ((regsPtr->control & SCSI_COMMAND) == 0) {
  369.         Reset(ctrlPtr);
  370.         return(DEV_HANDSHAKE_ERROR);
  371.     }
  372.         regsPtr->commandStatus = *charPtr;
  373.     charPtr++;
  374.     }
  375. status = Wait(ctrlPtr, SCSI_INTERRUPT_REQUEST, TRUE);
  376.     if (status == SUCCESS) {
  377.         unsigned char statusByte;
  378.         int    residual;
  379.         residual = -regsPtr->dmaCount -1;
  380.         status = GetStatusByte(ctrlPtr,&statusByte);
  381.         RequestDone(devPtr, scsiCmdPtr, status, statusByte, size-residual);
  382.     }
  383.     return status;
  384. }
  385.  
  386. /*
  387.  *----------------------------------------------------------------------
  388.  *
  389.  * GetStatusByte --
  390.  *
  391.  *    Complete an SCSI command by getting the status bytes from
  392.  *    the device and waiting for the ``command complete''
  393.  *    message that follows the status bytes.  If the command has
  394.  *    additional ``sense data'' then this routine issues the
  395.  *    SCSI_REQUEST_SENSE command to get the sense data.
  396.  *
  397.  * Results:
  398.  *    An error code if the status didn't come through or it
  399.  *    indicated an error.
  400.  *
  401.  * Side effects:
  402.  *    None.
  403.  *
  404.  *----------------------------------------------------------------------
  405.  */
  406. static ReturnStatus
  407. GetStatusByte(ctrlPtr, statusBytePtr)
  408.     Controller *ctrlPtr;
  409.     unsigned char *statusBytePtr;
  410. {
  411.     register ReturnStatus status;
  412.     register volatile CtrlRegs *regsPtr;
  413.     short message;
  414.     char statusByte;
  415.     int numStatusBytes = 0;
  416.  
  417.     regsPtr = ctrlPtr->regsPtr;
  418.     *statusBytePtr = 0;
  419.     for (;;) {
  420.     /*
  421.      * Could probably wait either on the INTERUPT_REQUEST bit or the
  422.      * REQUEST bit.  Reading the byte out of the commandStatus
  423.      * register acknowledges the REQUEST and clears these bits.  Here
  424.      * we grab bytes until the MESSAGE bit indicates that all the
  425.      * status bytes have been received and that the byte in the
  426.      * commandStatus register is the message byte.
  427.      */
  428.     status = Wait(ctrlPtr, SCSI_REQUEST, TRUE);
  429.     if (status != SUCCESS) {
  430.         break;
  431.     }
  432.     if (regsPtr->control & SCSI_MESSAGE) {
  433.         message = regsPtr->commandStatus & 0xff;
  434.         break;
  435.     } else {
  436.         /*
  437.          * This is another status byte.  Place the first status
  438.          * bytes into the status block.
  439.          */
  440.         statusByte = regsPtr->commandStatus;
  441.         if (numStatusBytes < 1) {
  442.         *statusBytePtr = statusByte;
  443.         }
  444.         numStatusBytes++;
  445.         if (numStatusBytes> 5) {
  446.         status = FAILURE;
  447.         break;
  448.        }
  449.     }
  450.     }
  451.     Mach_MonPrintf("Got it %x  %x\n", statusByte, status);
  452.     return(status);
  453. }
  454.  
  455. /*
  456.  *----------------------------------------------------------------------
  457.  *
  458.  * Wait --
  459.  *
  460.  *    Wait for a condition in the SCSI controller.
  461.  *
  462.  * Results:
  463.  *    SUCCESS if the condition occurred before a threashold time limit,
  464.  *    DEV_TIMEOUT otherwise.
  465.  *
  466.  * Side effects:
  467.  *    This resets the SCSI bus if the reset parameter is true and
  468.  *    the condition bits are not set by the controller before timeout..
  469.  *
  470.  *----------------------------------------------------------------------
  471.  */
  472. static ReturnStatus
  473. Wait(ctrlPtr, condition, reset)
  474.     Controller *ctrlPtr;
  475.     int condition;
  476.     Boolean reset;
  477. {
  478.     volatile CtrlRegs *regsPtr = (volatile CtrlRegs *)ctrlPtr->regsPtr;
  479.     register int i;
  480.     ReturnStatus status = DEV_TIMEOUT;
  481.     register int control;
  482.  
  483.     for (i=0 ; i < SCSI_WAIT_LENGTH ; i++) {
  484.     control = regsPtr->control;
  485.     if (control & condition) {
  486.         return(SUCCESS);
  487.     }
  488.     if (control & SCSI_BUS_ERROR) {
  489.         status = DEV_DMA_FAULT;
  490.         break;
  491.     } else if (control & SCSI_PARITY_ERROR) {
  492.         status = DEV_DMA_FAULT;
  493.         break;
  494.     }
  495.     MACH_DELAY(10);
  496.     }
  497.     if (reset) {
  498.     Reset(ctrlPtr);
  499.     }
  500.     return(status);
  501. }
  502.  
  503. /*
  504.  *----------------------------------------------------------------------
  505.  *
  506.  * entryAvailProc --
  507.  *
  508.  *    Act upon an entry becomming available in the queue for this
  509.  *    controller. This routine is the Dev_Queue callback function that
  510.  *    is called whenever work becomes available for this controller. 
  511.  *    If the controller is not already busy we dequeue and start the
  512.  *    request.
  513.  *    NOTE: This routine is also called from DevSCSI0Intr to start the
  514.  *    next request after the previously one finishes.
  515.  *
  516.  * Results:
  517.  *    None.
  518.  *
  519.  * Side effects:
  520.  *    Request may be dequeue and submitted to the device. Request callback
  521.  *    function may be called.
  522.  *
  523.  *----------------------------------------------------------------------
  524.  */
  525.  
  526. static Boolean
  527. entryAvailProc(clientData, newRequestPtr) 
  528.    ClientData    clientData;    /* Really the Device this request ready. */
  529.    List_Links *newRequestPtr;    /* The new SCSI request. */
  530. {
  531.     register Device *devPtr; 
  532.     register Controller *ctrlPtr;
  533.     register ScsiCmd    *scsiCmdPtr;
  534.     ReturnStatus    status;
  535. int    i;
  536.  
  537.     devPtr = (Device *) clientData;
  538.     ctrlPtr = devPtr->ctrlPtr;
  539.     /*
  540.      * If we are busy (have an active request) just return. Otherwise 
  541.      * start the request.
  542.      */
  543.  
  544. again:
  545.     scsiCmdPtr = (ScsiCmd *) newRequestPtr;
  546.     devPtr = (Device *) clientData;
  547.      doneC = 0;
  548.     status = SendCommand( devPtr, scsiCmdPtr);
  549.     i = 0;
  550.     if (status != SUCCESS) {
  551.     Mach_MonPrintf("Bad2 0x%x\n", status); 
  552.     goto again;
  553.     }
  554.     /*    
  555.      * If the command couldn't be started do the callback function.
  556.      */
  557.     return TRUE;
  558.  
  559. }   
  560.  
  561.  
  562. /*
  563.  *----------------------------------------------------------------------
  564.  *
  565.  *  SpecialSenseProc --
  566.  *
  567.  *    Special function used for HBA generated REQUEST SENSE. A SCSI
  568.  *    command request with this function as a call back proc will
  569.  *    be processed by routine RequestDone as a result of a 
  570.  *    REQUEST SENSE. This routine is never called.
  571.  *
  572.  * Results:
  573.  *    None.
  574.  *
  575.  * Side effects:
  576.  *    None.
  577.  *
  578.  *----------------------------------------------------------------------
  579.  */
  580.  
  581. static int
  582. SpecialSenseProc()
  583. {
  584. }
  585.  
  586.  
  587. /*
  588.  *----------------------------------------------------------------------
  589.  *
  590.  * RequestDone --
  591.  *
  592.  *    Process a request that has finished. Unless a SCSI check condition
  593.  *    bit is present in the status returned, the request call back
  594.  *    function is called.  If check condition is set we fire off a
  595.  *    SCSI REQUEST SENSE to get the error sense bytes from the device.
  596.  *
  597.  * Results:
  598.  *    None.
  599.  *
  600.  * Side effects:
  601.  *    The call back function may be called.
  602.  *
  603.  *----------------------------------------------------------------------
  604.  */
  605.  
  606. static void
  607. RequestDone(devPtr,scsiCmdPtr,status,scsiStatusByte,amountTransferred)
  608.     Device    *devPtr;    /* Device for request. */
  609.     ScsiCmd    *scsiCmdPtr;    /* Request that finished. */
  610.     ReturnStatus status;    /* Status returned. */
  611.     unsigned char scsiStatusByte;    /* SCSI Status Byte. */
  612.     int        amountTransferred; /* Amount transferred by command. */
  613. {
  614.     ReturnStatus    senseStatus;
  615.     Controller            *ctrlPtr = devPtr->ctrlPtr;
  616.  
  617.  
  618.     if (ctrlPtr->dmaState != DMA_INACTIVE) {
  619.     VmMach_DMAFree(scsiCmdPtr->bufferLen,ctrlPtr->dmaBuffer);
  620.     ctrlPtr->dmaState = DMA_INACTIVE;
  621.     }
  622.     Mach_MonPrintf("Request done %d bytes status 0x%x scsi 0x%x addr 0x%x/%d\n",
  623.         amountTransferred, status, scsiStatusByte, 
  624.         scsiCmdPtr->buffer, scsiCmdPtr->bufferLen);
  625.     /*
  626.      * First check to see if this is the reponse of a HBA generated 
  627.      * REQUEST SENSE command.  If this is the case, we can process
  628.      * the callback of the frozen command for this device and
  629.      * allow the flow of command to the device to be resummed.
  630.      */
  631.     if (scsiCmdPtr->doneProc == SpecialSenseProc) {
  632.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  633.     doneC = 1;
  634.     (devPtr->frozen.scsiCmdPtr->doneProc)(devPtr->frozen.scsiCmdPtr, 
  635.             SUCCESS,
  636.             devPtr->frozen.statusByte, 
  637.             devPtr->frozen.amountTransferred,
  638.             amountTransferred,
  639.             devPtr->senseBuffer);
  640.      MASTER_LOCK(&(ctrlPtr->mutex));
  641.      SET_CTRL_FREE(ctrlPtr);
  642.      return;
  643.     }
  644.     /*
  645.      * This must be a outside request finishing. If the request 
  646.      * suffered an error or the HBA or the scsi status byte
  647.      * says there is no error sense present, we can do the
  648.      * callback and free the controller.
  649.      */
  650.     if ((status != SUCCESS) || !SCSI_CHECK_STATUS(scsiStatusByte)) {
  651.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  652.     (scsiCmdPtr->doneProc)(scsiCmdPtr, status, scsiStatusByte,
  653.                    amountTransferred, 0, (char *) 0);
  654.     doneC = 1;
  655.      MASTER_LOCK(&(ctrlPtr->mutex));
  656.      SET_CTRL_FREE(ctrlPtr);
  657.      return;
  658.    } 
  659.  
  660.    /*
  661.     * If we got here than the SCSI command came back from the device
  662.     * with the CHECK bit set in the status byte.
  663.     * Need to perform a REQUEST SENSE. Move the current request 
  664.     * into the frozen state and issue a REQUEST SENSE. 
  665.     */
  666.    devPtr->frozen.scsiCmdPtr = scsiCmdPtr;
  667.    devPtr->frozen.statusByte = scsiStatusByte;
  668.    devPtr->frozen.amountTransferred = amountTransferred;
  669.    DevScsiSenseCmd((ScsiDevice *)devPtr, DEV_MAX_SENSE_BYTES, 
  670.            devPtr->senseBuffer, &(devPtr->SenseCmd));
  671.    devPtr->SenseCmd.doneProc = SpecialSenseProc,
  672.    senseStatus = SendCommand(devPtr, &(devPtr->SenseCmd));
  673.    /*
  674.     * If we got an HBA error on the REQUEST SENSE we end the outside 
  675.     * command with the SUCCESS status but zero sense bytes returned.
  676.     */
  677.    if (senseStatus != SUCCESS) {
  678.         MASTER_UNLOCK(&(ctrlPtr->mutex));
  679.     (scsiCmdPtr->doneProc)(scsiCmdPtr, status, scsiStatusByte,
  680.                    amountTransferred, 0, (char *) 0);
  681.     MASTER_LOCK(&(ctrlPtr->mutex));
  682.     SET_CTRL_FREE(ctrlPtr);
  683.    }
  684. }
  685.  
  686. /*
  687.  *----------------------------------------------------------------------
  688.  *
  689.  * DevSCSI0Intr --
  690.  *
  691.  *    Handle interrupts from the SCSI controller.  This has to poll
  692.  *    through the possible SCSI controllers to find the one generating
  693.  *    the interrupt.  The usual action is to wake up whoever is waiting
  694.  *    for I/O to complete.  This may also start up another transaction
  695.  *    with the controller if there are things in its queue.
  696.  *
  697.  * Results:
  698.  *    TRUE if the SCSI controller was responsible for the interrupt
  699.  *    and this routine handled it.
  700.  *
  701.  * Side effects:
  702.  *    Usually a process is notified that an I/O has completed.
  703.  *
  704.  *----------------------------------------------------------------------
  705.  */
  706. Boolean
  707. DevSCSI0Intr(clientDataArg)
  708.     ClientData    clientDataArg;
  709. {
  710.     register Controller *ctrlPtr;
  711.     Device    *devPtr;
  712.     volatile CtrlRegs *regsPtr;
  713.     int        residual;
  714.     ReturnStatus    status;
  715.     List_Links    *newRequestPtr;
  716.     unsigned char statusByte;
  717.     ClientData    clientData;
  718.  
  719.      ctrlPtr = (Controller *) Controllers[0];
  720.     regsPtr = ctrlPtr->regsPtr;
  721.     devPtr = ctrlPtr->devPtr;
  722.     MASTER_LOCK(&(ctrlPtr->mutex));
  723.     if (regsPtr->control & SCSI_INTERRUPT_REQUEST) {
  724.     if (regsPtr->control & SCSI_BUS_ERROR) {
  725.         Mach_MonPrintf("Warning:  SCSI bus error\n");
  726.         if (regsPtr->dmaCount >= 0) {
  727.         /*
  728.          * A DMA overrun.  Unlikely with a disk but could
  729.          * happen while reading a large tape block.  Consider
  730.          * the I/O complete with no residual bytes
  731.          * un-transferred.
  732.                  */
  733.         residual = 0;
  734.         } else {
  735.         /*
  736.          * A real Bus Error.  Complete the I/O but flag an error.
  737.          * The residual is computed because the Bus Error could
  738.          * have occurred after a number of sectors.
  739.          */
  740.         residual = -regsPtr->dmaCount -1;
  741.         }
  742.         /*
  743.          * The board needs to be reset to clear the Bus Error
  744.          * condition so no status bytes are grabbed.
  745.          */
  746.         Reset(ctrlPtr);
  747.         status = DEV_DMA_FAULT;
  748.         RequestDone(devPtr, ctrlPtr->scsiCmdPtr, status, 0,
  749.             ctrlPtr->scsiCmdPtr->bufferLen - residual);
  750.         MASTER_UNLOCK(&(ctrlPtr->mutex));
  751.         return(TRUE);
  752.     } else {
  753.         /*
  754.          * Normal command completion.  Compute the residual,
  755.          * the number of bytes not transferred, check for
  756.          * odd transfer sizes, and finally get the completion
  757.          * status from the device.
  758.          */
  759.         if (!IS_CTRL_BUSY(ctrlPtr)) {
  760.             Mach_MonPrintf(" SCSI no command\n");
  761.  
  762.         Reset(ctrlPtr);
  763.         MASTER_UNLOCK(&(ctrlPtr->mutex));
  764.         return(TRUE);
  765.         }
  766.         residual = -regsPtr->dmaCount -1;
  767.         if (regsPtr->control & SCSI_ODD_LENGTH) {
  768.         /*
  769.          * On a read the last odd byte is left in the data
  770.          * register.  On both reads and writes the number
  771.          * of bytes transferred as determined from dmaCount
  772.          * is off by one.  See Page 8 of Sun's SCSI
  773.          * Programmers' Manual.
  774.          */
  775.         if (!ctrlPtr->scsiCmdPtr->dataToDevice) {
  776.           *(volatile char *)(VMMACH_DMA_START_ADDR + regsPtr->dmaAddress) =
  777.             regsPtr->data;
  778.             residual--;
  779.         } else {
  780.             residual++;
  781.         }
  782.         }
  783.         status = GetStatusByte(ctrlPtr,&statusByte);
  784.         RequestDone(devPtr, ctrlPtr->scsiCmdPtr, status, 
  785.             statusByte,
  786.             ctrlPtr->scsiCmdPtr->bufferLen - residual);
  787.         MASTER_UNLOCK(&(ctrlPtr->mutex));
  788.         return(TRUE);
  789.     }
  790.     }
  791.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  792.     return (FALSE);
  793. }
  794.  
  795. /*
  796.  *----------------------------------------------------------------------
  797.  *
  798.  * ReleaseProc --
  799.  *
  800.  *    Device release proc for controller.
  801.  *
  802.  * Results:
  803.  *    None.
  804.  *
  805.  * Side effects:
  806.  *    None.
  807.  *
  808.  *----------------------------------------------------------------------
  809.  */
  810. /*ARGSUSED*/
  811. static ReturnStatus
  812. ReleaseProc(scsiDevicePtr)
  813.     ScsiDevice    *scsiDevicePtr;
  814. {
  815.     return SUCCESS;
  816. }
  817. nullp() { }
  818.  
  819. /*
  820.  *----------------------------------------------------------------------
  821.  *
  822.  * DevSCSI0Init --
  823.  *
  824.  *    Check for the existant of the Sun SCSI0 HBA controller. If it
  825.  *    exists allocate data stuctures for it.
  826.  *
  827.  * Results:
  828.  *    TRUE if the controller exists, FALSE otherwise.
  829.  *
  830.  * Side effects:
  831.  *    Memory may be allocated.
  832.  *
  833.  *----------------------------------------------------------------------
  834.  */
  835. ClientData
  836. DevSCSI0Init(ctrlLocPtr)
  837.     DevConfigController    *ctrlLocPtr;    /* Controller location. */
  838. {
  839.     int    ctrlNum;
  840.     Boolean    found;
  841.     Controller *ctrlPtr;
  842.     int    i,j;
  843.  
  844.     /*
  845.      * See if the controller is there. 
  846.      */
  847.     ctrlNum = ctrlLocPtr->controllerID;
  848.     /*
  849.      * It's there. Allocate and fill in the Controller structure.
  850.      */
  851.     Controllers[ctrlNum] = ctrlPtr = (Controller *) malloc(sizeof(Controller));
  852.     ctrlPtr->regsPtr = (volatile CtrlRegs *) (ctrlLocPtr->address);
  853.     ctrlPtr->regsPtr->intrVector = ctrlLocPtr->vectorNumber;
  854.     ctrlPtr->name = ctrlLocPtr->name;
  855.     Sync_SemInitDynamic(&(ctrlPtr->mutex),ctrlPtr->name);
  856.     /* 
  857.      * Initialized the name, device queue header, and the master lock.
  858.      * The controller comes up with no devices active and no devices
  859.      * attached.  Reserved the devices associated with the 
  860.      * targetID of the controller (7).
  861.      */
  862.     ctrlPtr->scsiCmdPtr = (ScsiCmd *) NIL;
  863.     Controllers[0] = ctrlPtr;
  864.     boot_Poll = nullp;
  865.     boot_SendSCSICommand = entryAvailProc;
  866.     Reset(ctrlPtr);
  867.     return (ClientData) ctrlPtr;
  868. }
  869.  
  870.  
  871. /*
  872.  *----------------------------------------------------------------------
  873.  *
  874.  * DevSCSI0ttachDevice --
  875.  *
  876.  *    Attach a SCSI device using the Sun SCSI0 HBA. 
  877.  *
  878.  * Results:
  879.  *    None.
  880.  *
  881.  * Side effects:
  882.  *    None.
  883.  *
  884.  *----------------------------------------------------------------------
  885.  */
  886.  
  887. ScsiDevice   *
  888. DevSCSI0AttachDevice(devicePtr, insertProc)
  889.     Fs_Device    *devicePtr;     /* Device to attach. */
  890.     void    (*insertProc)(); /* Queue insert procedure. */
  891. {
  892.     Device *devPtr;
  893.     Controller    *ctrlPtr;
  894.     char   tmpBuffer[512];
  895.     int       length;
  896.     int       ctrlNum;
  897.     int       targetID, lun;
  898.  
  899.     ctrlPtr = Controllers[0];
  900.     targetID = SCSI_TARGET_ID(devicePtr);
  901.     lun = SCSI_LUN(devicePtr);
  902.     /*
  903.      * Allocate a device structure for the device and fill in the
  904.      * handle part. This must be created before we grap the MASTER_LOCK.
  905.      */
  906.     devPtr = (Device *) malloc(sizeof(Device)); 
  907.     devPtr->handle.locationName = "Unknown";
  908.     devPtr->handle.LUN = lun;
  909.     devPtr->handle.releaseProc = ReleaseProc;
  910.     devPtr->handle.maxTransferSize = 63*1024;
  911.  
  912.     ctrlPtr->devicePtr = devPtr;
  913.     devPtr->targetID = targetID;
  914.     devPtr->ctrlPtr = ctrlPtr;
  915.  
  916.     devPtr->handle.locationName = "SCSI0";
  917.  
  918.     return (ScsiDevice *) devPtr;
  919. }
  920.  
  921. #endif
  922.